home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
PMACROS.H
< prev
next >
Wrap
Text File
|
1989-08-17
|
7KB
|
377 lines
;Assembly language macros for C compiler independence. Assemble with /mx
;to ensure mixed case symbols.
ifndef MSC
MSC equ 0
endif
ifndef TURBO
TURBO equ 0
endif
ifndef AZTEC
AZTEC equ 0
endif
if MSC + TURBO + AZTEC NE 1
.err One and only one of MSC, TURBO, and AZTEC should be defined.
endif
;Copyright, 1987, 1988, Russell Nelson
;Permission to use, copy, modify and distribute this software for any purpose
;and without fee is hereby granted, provided that the above copyright notice
;appears in all copies and that both that copyright notice and this permission
;appear in supporting documentation. Russell Nelson MAKES NO REPRESENTATIONS
;ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED
;"AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
; .xlist
;Note that symbols defined by these macros (pubproc, extproc, pubvar, extvar)
;should be referred by users of this package as 's@' where 's' is the defined
;symbol. This hides the compiler's underscore convention. For example,
; include pmacros.h
; extproc foo
; pubproc bar
; call foo@
; pend bar
;begin a public procedure and label it 'a'. If 'd' is absent, then default
;to what LARGECODE says, otherwise 'd' must be 'far' or 'near'.
;Terminated by pend.
pubproc macro a,d
cseg
if AZTEC
public a&_
a&@ equ a&_
else
public _&a
a&@ equ _&a
endif
ifb <d>
ifdef LARGECODE
if AZTEC
a&_ proc far
else
_&a proc far
endif
first_param = 6
else
if AZTEC
a&_ proc near
else
_&a proc near
endif
first_param = 4
endif
else ;ifb
if AZTEC
a&_ proc d
else
_&a proc d
endif
ifidn <d>,<far>
first_param = 6
else
first_param = 4
endif
endif
endm
;used internally to expand first_param and increment it.
_param macro a,o,t,n
a equ t ptr o[bp]
first_param = first_param + n
endm
;declare a parameter. Use byte, word, ptr, or fptr (function pointer).
param macro a,t
ifidn <t>,<byte>
_param a,%first_param,byte,2
endif
ifidn <t>,<word>
_param a,%first_param,word,2
endif
ifidn <t>,<ptr>
ifdef LARGEDATA
_param a,%first_param,dword,4
else
_param a,%first_param,word,2
endif
endif
ifidn <t>,<fptr>
ifdef LARGECODE
_param a,%first_param,dword,4
else
_param a,%first_param,word,2
endif
endif
endm
;load a data pointer.
ldptr macro off_reg,var,seg_reg
ifdef LARGEDATA
l&seg_reg off_reg,var
else
mov off_reg,var
endif
endm
;define a public procedure with parameters, like so:
;procdef foo, <<bar, word>, <baz, ptr>>
;Terminated by pret, pend
procdef macro n,a
pubproc n
irp one_param,<a>
param one_param
endm
push bp
mov bp,sp
endm
;return from a procedure with parameters. Pairs with procdef
pret macro
pop bp
ret
endm
;end a public procedure. Pairs with pubproc
pend macro a
if AZTEC
a&_ endp
else
_&a endp
endif
csegend
endm
;define an external procedure called 'a'. If 'd' is absent, then default
;to what LARGECODE says, otherwise 'd' must be 'far' or 'near'.
extproc macro a,d
ifb <d>
ifdef LARGECODE
if AZTEC
extrn a&_: far
else
extrn _&a: far
endif
else
if AZTEC
extrn a&_: near
else
extrn _&a: near
endif
endif
else ;ifb
if AZTEC
extrn a&_: d
else
extrn _&a: d
endif
endif
if AZTEC
a&@ equ a&_
else
a&@ equ _&a
endif
endm
;open the code segment
cseg macro
if AZTEC
codeseg segment byte public 'code'
assume cs:codeseg,ds:dataseg
endif
if TURBO
_TEXT segment byte public 'CODE'
dgroup group _DATA
assume cs:_TEXT,ds:dgroup
endif
if MSC
_TEXT SEGMENT WORD PUBLIC 'CODE'
assume cs:_TEXT,ds:DGROUP
endif
endm
;close the code segment
csegend macro
if AZTEC
codeseg ends
endif
if TURBO or MSC
_TEXT ends
endif
endm
;assume that the ds is the code segment
dscode macro
if AZTEC
assume ds:codeseg
endif
if TURBO or MSC
assume ds:_TEXT
endif
endm
;Return the data segment
getds macro
if AZTEC
mov ax,dataseg
endif
if TURBO
mov ax,dgroup
endif
if MSC
mov ax,DGROUP
endif
endm
;open the data segment
dseg macro
if AZTEC
dataseg segment word public 'data'
endif
if TURBO or MSC
_DATA segment word public 'DATA'
endif
endm
;close the data segment
dsegend macro
if AZTEC
dataseg ends
endif
if TURBO or MSC
_DATA ends
endif
endm
;define a public variable
;use it like so: pubvar a,<dw 0>
pubvar macro n,d
if AZTEC
public n&_
n&_ d
n&@ equ n&_
endif
if TURBO or MSC
public _&n
_&n d
n&@ equ _&n
endif
endm
;define an external variable
;use it like so: extvar a,word
; or extvar a,byte
extvar macro n,d
if AZTEC
extrn n&_: d
n&@ equ n&_
endif
if TURBO or MSC
extrn _&n: d
n&@ equ _&n
endif
endm
; Conditional DS save/restore macros
pushds macro
ifdef LARGEDATA
push ds
endif
endm
popds macro
ifdef LARGEDATA
pop ds
endif
endm
; Conditional ES save/restore macros
pushes macro
ifdef LARGEDATA
push es
endif
endm
popes macro
ifdef LARGEDATA
pop es
endif
endm
;define the segments so that they exist.
dseg
dsegend
if MSC
CONST SEGMENT WORD PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
DGROUP GROUP CONST,_BSS,_DATA
endif
cseg
csegend
;define an interrupt handler.
inthandler macro xxxname,xxxnum
dseg
extvar sssave,word
extvar spsave,word
extvar intstk,byte
dsegend
extproc doret
extproc xxxname&int
pubproc xxxname&xxxnum&vec
cli ; this code is not re-entrant, so make sure it
; is not interrupted. some multi-taskers
; intercept interrupt handlers, so be careful!
push ax ; save ax first.
push ds ; save on user stack
getds
mov ds,ax
mov sssave@,ss ; stash user stack context
mov spsave@,sp
mov ss,ax ; set up interrupt stack
lea sp,intstk@
push bx ; save user regs on interrupt stack
push cx
push dx
push bp
push si
push di
push es
ifndef LARGEDATA
mov es,ax ; small data assumes ES == DS
endif
if TURBO or MSC
cld ; in case "movsb" or "movsw" is used
endif
mov ax,xxxnum ; arg for service routine
push ax
call xxxname&int@
pop ax
jmp doret@
pend xxxname&xxxnum&vec
endm
assume cs:nothing,ds:nothing,es:nothing,ss:nothing
; .list